<template>
  <div :class="getComponentClass('sh-form')" :style="padding">
    <Form
      ref="ShFormRef"
      :model="formData.formModel"
      :rules="rules"
      :label-width="labelWidth"
      :labelPosition="labelPosition"
    >
      <template v-for="(item, index) in configs" :key="index">
        <sh-title v-if="item.label" class="ivu-mb" :key="index + 'span'" :prefix="item.prefix">
          {{ item.label }}
          <slot :name="item.labelSlot" />
        </sh-title>
        <sh-form-row :gutter="gutter" :dataSource="item" :dictData="dictData" @change="changeItem">
          <template v-for="v in getSlots(item.list)" #[v.slot]="{ item }">
            <slot :name="v.slot" :item="v" />
          </template>
        </sh-form-row>
      </template>
    </Form>
  </div>
</template>
<script setup>
import { onMounted, ref, getCurrentInstance } from 'vue';
import ShFormRow from './sh-form-row.vue';
import { useClass } from '../../utils/useClass';
import { useComputed } from './utils/useComputed';
import { useApi } from './utils/useApi';
import { useDependencyInjection } from '../../utils/useDependencyInjection';
import { useForm } from './utils/useForm';
const { proxy } = getCurrentInstance();

const props = defineProps({
  // 传入的数据
  model: {
    type: Object,
    default: () => {},
  },
  // 表单总入参项，定义各表单信息、类型等
  configs: {
    type: Array,
    default: () => [],
  },
  // 表单fe-form的内边距
  padding: {
    type: String,
  },
  // 各表单项，左边标题label的宽度
  labelWidth: {
    type: Number,
    default: 80,
  },
  labelPosition: {
    type: String,
    default: 'right',
    validator(value) {
      return ['left', 'right', 'top'].includes(value);
    },
  },
  // 表单的校验
  rules: {
    type: Object,
    default: () => {},
  },
  // 两个表单项之间的间距
  gutter: {
    type: Number,
    default: 20,
  },
  // 是否展示title的前缀
  prefix: {
    type: Boolean,
    default: true,
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  readonly: {
    type: Boolean,
    default: false,
  },
  openUpdate: {
    type: Boolean,
    default: false,
  },
});
const emits = defineEmits(['change', 'saveRef']);
const ShFormRef = ref(null);
let dictData = ref({});

const { getSlots } = useComputed(props, emits);
const { formData, changeItem, setFilesValue, getFilesValue } = useForm(props, emits);
const { setProvide } = useDependencyInjection();
// formModel以函数的形式注入，实现 provide和inject的双向绑定
setProvide(['formData', 'labelWidth', 'disabled', 'readonly', 'openUpdate'], { formData: formData, ...props });

const { getDictData } = useApi(proxy.$VIEWUI.apiConfigs, emits);
getDictData(dictData, props.configs);

const { getComponentClass } = useClass();

defineExpose({ setFilesValue, getFilesValue });
onMounted(() => {
  emits('saveRef', ShFormRef);
});
</script>
